#include <math.h>

using std::cout;
Matrix3D::Matrix3D(void) {
	for (int i=0; i<3; i++){ 
		for (int j=0; j<3; j++){
			this->setCoord(0 , i, j);
		}
	}
}

Matrix3D::Matrix3D(double m[3][3]){
	this->setCoords(m);
}

Matrix3D::Matrix3D(Matrix3D *m){
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			this->setCoord(m->getCoord(i, j), i, j);
		}
	}
}

Matrix3D::~Matrix3D(void){
	//
}

void Matrix3D::setCoords(double m[3][3]){
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			this->coord[i][j] = m[i][j];
		}
	}
}

void Matrix3D::setCoord(double newcoord, int i, int j){
	this->coord[i][j] = newcoord;
}

double Matrix3D::getCoord(int i, int j){
	return this->coord[i][j];
}

void Matrix3D::getCoords(double m[3][3]){
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			m[i][j] = this->getCoord( i, j);
		}
	}
}

Matrix3D* Matrix3D::getIdentidade(){
	Matrix3D *iden = new Matrix3D();
	for (int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			if (i == j){
				iden->setCoord(1 ,i ,j);
			} else {
				iden->setCoord(0 , i, j);
			}
		}
	}
	return iden;
}

Matrix3D* Matrix3D::soma(Matrix3D *m){
	Matrix3D *result = new Matrix3D();
	for (int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			result->setCoord((this->getCoord(i , j) + m->getCoord(i , j)), i, j);
		}
	}
	return result;
}

Matrix3D* Matrix3D::subtracao(Matrix3D *m){
	Matrix3D *result = new Matrix3D();
	for (int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			result->setCoord((this->getCoord(i , j) - m->getCoord(i , j)), i, j);
		}
	}
	return result;
}

Matrix3D* Matrix3D::multiplicacao(Matrix3D *m){
	Matrix3D* result = new Matrix3D();
	double soma;
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			soma = 0;
			for(int k=0; k<3; k++){
				soma = soma + (this->getCoord(i, k)* m->getCoord(k , j));
			}
			
			result->setCoord(soma , i, j);
			
		}
	}
	return result;
}

Matrix3D* Matrix3D::multiplicacao( double escalar){
	
	Matrix3D* result = new Matrix3D();
	
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			result->setCoord( (this->getCoord( i, j) * escalar) , i, j);
		}
	}
	return result;
}



double Matrix3D::determinante(){
	return ( (this->getCoord(0,0)*this->getCoord(1,1)*this->getCoord(2,2)) + 
			 (this->getCoord(0,1)*this->getCoord(1,2)*this->getCoord(2,0)) +
			 (this->getCoord(0,2)*this->getCoord(1,0)*this->getCoord(2,1)) -
			 (this->getCoord(0,2)*this->getCoord(1,1)*this->getCoord(2,0)) -
			 (this->getCoord(0,0)*this->getCoord(1,2)*this->getCoord(2,1)) -
			 (this->getCoord(0,1)*this->getCoord(1,0)*this->getCoord(2,2)) ); 
}

Matrix3D* Matrix3D::transposta(){
	Matrix3D *result = new Matrix3D();
	for(int i=0; i<3; i++){
		for(int j=0; j<3; j++){
			result->setCoord( this->getCoord( i, j), j, i);
		}
	}
	return result;
}

void Matrix3D::print() {
	for (int i = 0;i < 3;i++) {
		for (int j = 0;j < 3;j++) {
			cout << this->getCoord(i,j) << "\t";
		}
		cout << "\n";
	}
}


